﻿using UnityEngine;

namespace ET
{
    [ObjectSystem]
    public class TurnComponentUpdateSystem: UpdateSystem<TurnComponent>
    {
        public override void Update(TurnComponent self)
        {
            self.Update();
        }
    }

    public class TurnComponent: Entity
    {
        // turn
        public Quaternion To;
        public Quaternion From;
        public float t = float.MaxValue;
        public float TurnTime = 0.1f;

        public void Update()
        {
            UpdateTurn();
        }

        private void UpdateTurn()
        {
            //Log.Debug($"update turn: {this.t} {this.TurnTime}");
            if (this.t > this.TurnTime)
            {
                return;
            }

            this.t += Time.deltaTime;

            Quaternion v = Quaternion.Slerp(this.From, this.To, this.t / this.TurnTime);
            this.GetParent<Unit>().Rotation = v;
        }

        /// <summary>
        /// 改变Unit的朝向
        /// </summary>
        public void Turn2D(Vector3 dir, float turnTime = 0.1f)
        {
            Vector3 nexpos = this.GetParent<Unit>().GetComponent<GameObjectComponent>().GameObject.transform.position + dir;
            Turn(nexpos, turnTime);
        }

        /// <summary>
        /// 改变Unit的朝向
        /// </summary>
        public void Turn(Vector3 target, float turnTime = 0.1f)
        {
            Quaternion quaternion = PositionHelper.GetVector3ToQuaternion(this.GetParent<Unit>().Position, target);

            this.To = quaternion;
            this.From = this.GetParent<Unit>().Rotation;
            this.t = 0;
            this.TurnTime = turnTime;
        }

        /// <summary>
        /// 改变Unit的朝向
        /// </summary>
        /// <param name="angle">与X轴正方向的夹角</param>
        public void Turn(float angle, float turnTime = 0.1f)
        {
            Quaternion quaternion = PositionHelper.GetAngleToQuaternion(angle);

            this.To = quaternion;
            this.From = this.GetParent<Unit>().Rotation;
            this.t = 0;
            this.TurnTime = turnTime;
        }

        public void Turn(Quaternion quaternion, float turnTime = 0.1f)
        {
            this.To = quaternion;
            this.From = this.GetParent<Unit>().Rotation;
            this.t = 0;
            this.TurnTime = turnTime;
        }

        public void TurnImmediately(Quaternion quaternion)
        {
            this.GetParent<Unit>().Rotation = quaternion;
        }

        public void TurnImmediately(Vector3 target)
        {
            Vector3 nowPos = this.GetParent<Unit>().Position;
            if (nowPos == target)
            {
                return;
            }

            Quaternion quaternion = PositionHelper.GetVector3ToQuaternion(this.GetParent<Unit>().Position, target);
            this.GetParent<Unit>().Rotation = quaternion;
        }

        public void TurnImmediately(float angle)
        {
            Quaternion quaternion = PositionHelper.GetAngleToQuaternion(angle);
            this.GetParent<Unit>().Rotation = quaternion;
        }

        public override void Dispose()
        {
            if (this.IsDisposed)
            {
                return;
            }

            base.Dispose();
            To = Quaternion.identity;
            From = Quaternion.identity;
            t = float.MaxValue;
            TurnTime = 0.1f;
        }
    }
}